using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using IQIGame.Onigao.GameAOT;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    /// <summary>
    /// 和GameLauncher区分，方便之后能够使用钩子思路来热更热更模块
    /// </summary>
    public static class ProcedureEntry
    {
        /// <summary>
        /// 常驻Resloader，永不卸载
        /// </summary>
        public static ResLoader permanentResloader { get; } = ResLoader.Create();

        public static async UniTaskVoid EnterGame()
        {
            //初始化并发对象池
            ConcurrentClassPool<ReceivePackage>.Init(2);//目前最多2个channel
            ConcurrentClassPool<SendPackage>.Init((NetSession.CACHE_MESSAGE_COUNT + 1) * 2);
            ConcurrentClassPool<PacketHeader>.Init(2);//目前最多2个channel

            //加载配置表
            await TableCenter.LoadTables();
            //初始化底层框架
            FrameworkEntry.Instance.EnterGame();
            //初始化框架扩展层
            await InitFrameworkExt();
            await ManagerCenter.Render.InitRenderManager();
            //注册UI内部全局事件管理器创建函数
            UIGlobalEventControllerFactory.RegisterCreateFunc(UIMsgDispatcher.NewFromPool);
            //加载一些常驻业务资源
            GamePermanentResMgr.Instance.Init(permanentResloader);
            await GamePermanentResMgr.Instance.Load();
            //注册各游戏进程（Procedure）
            ProcedureFSM.Instance.AddState<ProcedureLaunch>();
            ProcedureFSM.Instance.AddState<ProcedureLogin>();
            ProcedureFSM.Instance.AddState<ProcedureGame>();
            ProcedureFSM.Instance.AddState<ProcedureReset>();
            //开启Launch进程
            ProcedureFSM.Instance.ChangeState<ProcedureLaunch>();
        }

        /// <summary>
        /// 初始化框架扩展层管理器中心
        /// </summary>
        /// <returns></returns>
        private static async UniTask InitFrameworkExt()
        {
            //该资源和实例不会被销毁和卸载
            GameObject customFramworkPrefab = await permanentResloader.LoadABAssetAwait<GameObject>("Res/03_Prefabs/Framework/FrameworkExt.prefab");
            GameObject customFramwork = UnityEngine.Object.Instantiate(customFramworkPrefab);
            customFramwork.name = customFramworkPrefab.name;

            GameLauncher launcher = UnityEngine.Object.FindObjectOfType<GameLauncher>();

#if UNITY_EDITOR
            Transform originalTrans = launcher.transform.Find("FrameworkExt");
            if (originalTrans != null)
            {
                UnityEngine.Object.Destroy(originalTrans.gameObject);
            }
#endif

            customFramwork.transform.SetParent(launcher.transform, false);

#if UNITY_EDITOR
            FrameworkEntry entry = launcher.GetComponentInChildren<FrameworkEntry>();
            customFramwork.transform.SetSiblingIndex(entry.transform.GetSiblingIndex() + 1);
#endif
            //customFramwork需要热更新，将实时被加载出来，然后实例化
            //该GameObject下有很多依赖MonoBehaviour的节点，这些MonoBehaviour被用作各个模块的配置，必须等待他们的Start执行完毕，才能保证后续模块被使用时是正确的
            //为了确保customFramwork上的组件Start执行完毕，这里强制延迟一帧，Start会在下一帧PlayerLoop和Update之前先执行。
            await UniTask.DelayFrame(1);
        }
    }
}

